#include "stdafx.h"
#include "Link.h"

Link :: Link(int len, int *cont, Link *pred)
{
	if (len)
	{
		context = new int [len];
		for (int i = 0; i < len; i++)
		{
			context[i] = cont [i+1];
		}
		amount = 1;
		unsigned char sym = cont[0];
		first = new Mini_link (sym);
	}
	else
	{
		Mini_link *next, *cur;
		unsigned char sym;
		first = new Mini_link (0);
		cur = first;
		for (int i = 1; i < 256; i++)
		{
			sym = i;
			next = new Mini_link (i);
			cur->SetNext(next);
			cur = next;
		}
		amount = 256;
	}
	esc = 1;
	length = len;
	predok = pred;
	left = NULL;
	right = NULL;
	balance = 0;
}

void Link :: Update(int sym)
{
	int k = 0;
	Mini_link *cur = first;
	if ((amount + esc) >= 0x3fff)
	{
		amount = 0;
		while (cur != NULL)
		{
			int amo = cur->Get_amount();
			amo -= amo>>1;
			cur->SetAmount(amo);
			amount += amo;
			cur = cur->GetNext();
		}
	}
	cur = first;
	while ((cur != NULL) && (k == 0))
	{
		if ((unsigned char)sym == cur->GetSym())
		{
			cur->Increase();
			k = 1;
		}
		else
			cur = cur->GetNext();
	}
	if (k == 0)
	{
		Mini_link *next = new Mini_link(sym);
		cur = first;
		first = next;
		first->SetNext(cur);
		esc++;
	}
	amount++;
}

int Link :: comparison(Link* cur)
{
	for (int i = length-1; i >= 0; i--)
		if (context[i] < cur->GetCont()[i])
			return -1;
		else if (context[i] > cur->GetCont()[i])
			return 1;	
	return 0;
}

int * Link :: GetCont()
{
	return context;
}


int Link :: GetLength()
{
	return length;
}

int Link :: GetEsc()
{
	return esc;
}

Link * Link :: GetPred()
{
	return predok;
}

Mini_link * Link :: GetFirst()
{
	return first;
}

Link :: ~Link()
{
	Mini_link * cur = first, *next;
	while (cur != NULL)
	{
		next = cur->GetNext();
		delete cur;
		cur = next;
	}
}